/** K.Arthur 6/21/2019 */

const { src, dest, series, parallel, watch } = require('gulp');
const gUglify = require('gulp-uglify');
const gCssmin = require('gulp-cssmin');
const gHtmlmin = require('gulp-html-minify');
const gRename = require('gulp-rename');
const gBabel = require('gulp-babel');
const gUseref = require('gulp-useref');
const gRev = require('gulp-rev');
const gRevReplace = require('gulp-rev-replace');
const gIf = require('gulp-if');
const gReplace = require('gulp-replace');
const gAutoprefixer = require('gulp-autoprefixer');
const gPx2rem = require('gulp-px2rem');
const gDelete = require('delete');

// conf
const CONF = {
  dest: 'dist',
  cmdOption: {
    rem: null,
    hashControll: 0,
    hashFilter: [],
    layer: 'layer'
  }
};
// parse command options
/**
 * usage:
 *   --layer set new layer name
 *   --rem set px2rem rootValue
 *   --filter add file to hashFilter
 */
(function() {
  process.argv.forEach((arg, idx) => {
    if (/^--/.test(arg)) {
      const key = arg.substr(2);
      const value = process.argv[idx + 1];

      if (value) {
        if (key === 'filter') {
          value.split(',').forEach(hf => {
            CONF.cmdOption.hashFilter.push(hf);
          });
        } else {
          CONF.cmdOption[key] = value;
        }
      }
    }
  });
})();

function gtHash() {
  const cssPath = /cmda-.*\.css$/;
  const jsPath = /cmda-.*\.js$/;
  const htmlPath = /src[\\/]{1,2}.*\.html$/;
  const viewsPath = /views[\\/]{1,2}.*\.html$/;
  const viewsPathDepth1 = /views[\\/]{1,2}[a-zA-Z0-9-_]*\.html/;
  const viewsPathDepth2 = /views[\\/]{1,2}[a-zA-Z0-9-_]*[\\/][a-zA-Z0-9-_]*\.html/;
  const templatePath = /views[\\/]{1,2}template[\\/]{1,2}/;
  const bootPath = /src[\\/]{1,2}[a-zA-Z0-9-_]*\.html$/;

  const cssCondition = file =>
    cssPath.test(file.path) && !/skip/.test(file.path);
  const cssConvertCondition = file => cssCondition(file) && CONF.cmdOption.rem;
  const jsCondition = file => jsPath.test(file.path) && !/skip/.test(file.path);
  const htmlCondition = file => htmlPath.test(file.path);
  const bootCondition = file => bootPath.test(file.path);
  const viewsCondition = file =>
    viewsPath.test(file.path) && !templatePath.test(file.path);
  const viewsDepth1Condition = file => viewsPathDepth1.test(file.path);
  const viewsDepth2Condition = file => viewsPathDepth2.test(file.path);
  const assetCondition = file =>
    !/\.html/.test(file.path) && !templatePath.test(file.path);

  return src(['src/*.html', 'src/views/**/*.html'])
    .pipe(gUseref())
    .pipe(gRev())
    .pipe(gRevReplace())
    .pipe(gIf(cssCondition, gAutoprefixer()))
    .pipe(
      gIf(
        cssConvertCondition,
        gPx2rem({ rootValue: CONF.cmdOption.rem, replace: true })
      )
    )
    .pipe(gIf(cssCondition, gReplace(/url\('.*?assets\//g, 'url(\'')))
    .pipe(gIf(cssCondition, gCssmin()))
    .pipe(gIf(jsCondition, gBabel()))
    .pipe(gIf(jsCondition, gUglify()))
    .pipe(gIf(jsCondition, gReplace(/url\('.*?assets\//g, 'url(\'')))
    .pipe(gIf(htmlCondition, gHtmlmin()))
    .pipe(
      gIf(viewsDepth1Condition, gReplace(/assets\/cmda/g, '../assets/cmda'))
    )
    .pipe(
      gIf(viewsDepth2Condition, gReplace(/assets\/cmda/g, '../../assets/cmda'))
    )
    .pipe(
      gRename(path => {
        if (path.extname === '.html') {
          if (path.dirname === '.') {
            const tailIndex = path.basename.lastIndexOf('-');
            path.basename = path.basename.substring(0, tailIndex);
          }
        }
      })
    )
    .pipe(gIf(bootCondition, dest(CONF.dest)))
    .pipe(gIf(viewsCondition, dest(`${CONF.dest}/views`)))
    .pipe(
      gRename(path => {
        if (path.extname === '.html') {
          for (let idx = 0; idx < CONF.cmdOption.hashFilter.length; idx++) {
            const tailIndex = path.basename.lastIndexOf('-');
            const newPath = path.basename.substring(0, tailIndex);
            if (newPath === CONF.cmdOption.hashFilter[idx]) {
              path.basename = newPath;
              break;
            }
          }
          if (+CONF.cmdOption.hashControll === 1) {
            path.basename = path.dirname;
            return;
          }
        }
      })
    )
    .pipe(gIf(viewsCondition, dest(`${CONF.dest}/views`)))
    .pipe(gIf(assetCondition, dest(CONF.dest, { overwrite: false })));
}


// gulp-task: no-Hash
function getBuild() {
  const cssPath = /cmda-.*\.css$/;
  const jsPath = /cmda-.*\.js$/;
  const htmlPath = /src[\\/]{1,2}.*\.html$/;
  const viewsPath = /views[\\/]{1,2}.*\.html$/;
  const viewsPathDepth1 = /views[\\/]{1,2}[a-zA-Z0-9-_]*\.html/;
  const viewsPathDepth2 = /views[\\/]{1,2}[a-zA-Z0-9-_]*[\\/][a-zA-Z0-9-_]*\.html/;
  const templatePath = /views[\\/]{1,2}template[\\/]{1,2}/;
  const bootPath = /src[\\/]{1,2}[a-zA-Z0-9-_]*\.html$/;

  const cssCondition = file =>
    cssPath.test(file.path) && !/skip/.test(file.path);
  const cssConvertCondition = file => cssCondition(file) && CONF.cmdOption.rem;
  const jsCondition = file => jsPath.test(file.path) && !/skip/.test(file.path);
  const htmlCondition = file => htmlPath.test(file.path);
  const bootCondition = file => bootPath.test(file.path);
  const viewsDepth1Condition = file => viewsPathDepth1.test(file.path);
  const viewsDepth2Condition = file => viewsPathDepth2.test(file.path);
  const viewsCondition = file =>
    viewsPath.test(file.path) && !templatePath.test(file.path);
  const assetCondition = file =>
    !/\.html/.test(file.path) && !templatePath.test(file.path);

  return src(['src/*.html', 'src/views/**/*.html'])
    .pipe(gUseref())
    .pipe(gRevReplace())
    .pipe(gIf(cssCondition, gAutoprefixer()))
    .pipe(
      gIf(
        cssConvertCondition,
        gPx2rem({ rootValue: CONF.cmdOption.rem, replace: true })
      )
    )
    .pipe(gIf(cssCondition, gReplace(/url\('.*?assets\//g, 'url(\'')))
    .pipe(gIf(cssCondition, gCssmin()))
    .pipe(gIf(jsCondition, gBabel()))
    .pipe(gIf(jsCondition, gUglify()))
    .pipe(gIf(jsCondition, gReplace(/url\('.*?assets\//g, 'url(\'')))
    .pipe(gIf(htmlCondition, gHtmlmin()))
    .pipe(
      gIf(viewsDepth1Condition, gReplace(/assets\/cmda/g, '../assets/cmda'))
    )
    .pipe(
      gIf(viewsDepth2Condition, gReplace(/assets\/cmda/g, '../../assets/cmda'))
    )
    .pipe(gIf(bootCondition, dest(CONF.dest)))
    .pipe(gIf(viewsCondition, dest(`${CONF.dest}/views`)))
    .pipe(gIf(assetCondition, dest(CONF.dest, { overwrite: false })));
}

// gulp-task: Copy
function gtCopyAssets() {
  return src('src/assets/**').pipe(dest(`${CONF.dest}/assets`));
}

// gulp-task: Clean
function gtClean(cb) {
  gDelete([CONF.dest], cb);
}

// gulp-task: New
function gtNew() {
  let firstLayer = CONF.cmdOption.layer;
  let secondLayer = CONF.cmdOption.layer;
  if (CONF.cmdOption.layer.indexOf(',') > -1) {
    [firstLayer, secondLayer] = CONF.cmdOption.layer.split(',');
  }
  console.log(CONF.cmdOption.layer)
  return src('src/views/template/**')
    .pipe(gReplace('template_template', `${firstLayer}_${secondLayer}`))
    .pipe(gReplace('template.js', `${secondLayer}.js`))
    .pipe(gReplace('template.css', `${secondLayer}.css`))
    .pipe(gRename(path => (path.basename = secondLayer)))
    .pipe(
      gIf(
        file => /\.(html|js|css)/.test(file.path),
        dest(`src/views/${firstLayer}`)
      )
    );
}
// 不带hash
function dev() {
  return watch('src/**', series(gtClean, parallel(gtCopyAssets, getBuild)));
}



// 带hash
function devHash() {
  return watch('src/**', series(gtClean, parallel(gtCopyAssets, gtHash)));
}

function hashBuild() {
  return series(gtClean, parallel(gtCopyAssets, gtHash));
}

exports.new = gtNew;
exports.clean = gtClean;
exports.default = series(gtClean, parallel(gtCopyAssets, getBuild));
exports.hashBuild = hashBuild();
exports.dev = series(dev);
exports.devHash = series(devHash);

